/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Services;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entity.Pet;
import java.util.ArrayList;
import java.util.List;
import Entity.Vacine;
import Entity.Appointment;
import Entity.MedicalRecord;
import Services.exceptions.IllegalOrphanException;
import Services.exceptions.NonexistentEntityException;
import Services.exceptions.PreexistingEntityException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author itachiu
 */
public class MedicalRecordJpaController implements Serializable {

    public MedicalRecordJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(MedicalRecord medicalRecord) throws PreexistingEntityException, Exception {
        if (medicalRecord.getPetList() == null) {
            medicalRecord.setPetList(new ArrayList<Pet>());
        }
        if (medicalRecord.getVacineList() == null) {
            medicalRecord.setVacineList(new ArrayList<Vacine>());
        }
        if (medicalRecord.getAppointmentList() == null) {
            medicalRecord.setAppointmentList(new ArrayList<Appointment>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Pet> attachedPetList = new ArrayList<Pet>();
            for (Pet petListPetToAttach : medicalRecord.getPetList()) {
                petListPetToAttach = em.getReference(petListPetToAttach.getClass(), petListPetToAttach.getPetPK());
                attachedPetList.add(petListPetToAttach);
            }
            medicalRecord.setPetList(attachedPetList);
            List<Vacine> attachedVacineList = new ArrayList<Vacine>();
            for (Vacine vacineListVacineToAttach : medicalRecord.getVacineList()) {
                vacineListVacineToAttach = em.getReference(vacineListVacineToAttach.getClass(), vacineListVacineToAttach.getVacinePK());
                attachedVacineList.add(vacineListVacineToAttach);
            }
            medicalRecord.setVacineList(attachedVacineList);
            List<Appointment> attachedAppointmentList = new ArrayList<Appointment>();
            for (Appointment appointmentListAppointmentToAttach : medicalRecord.getAppointmentList()) {
                appointmentListAppointmentToAttach = em.getReference(appointmentListAppointmentToAttach.getClass(), appointmentListAppointmentToAttach.getAppointmentPK());
                attachedAppointmentList.add(appointmentListAppointmentToAttach);
            }
            medicalRecord.setAppointmentList(attachedAppointmentList);
            em.persist(medicalRecord);
            for (Pet petListPet : medicalRecord.getPetList()) {
                MedicalRecord oldMedicalRecordOfPetListPet = petListPet.getMedicalRecord();
                petListPet.setMedicalRecord(medicalRecord);
                petListPet = em.merge(petListPet);
                if (oldMedicalRecordOfPetListPet != null) {
                    oldMedicalRecordOfPetListPet.getPetList().remove(petListPet);
                    oldMedicalRecordOfPetListPet = em.merge(oldMedicalRecordOfPetListPet);
                }
            }
            for (Vacine vacineListVacine : medicalRecord.getVacineList()) {
                MedicalRecord oldMedicalRecordOfVacineListVacine = vacineListVacine.getMedicalRecord();
                vacineListVacine.setMedicalRecord(medicalRecord);
                vacineListVacine = em.merge(vacineListVacine);
                if (oldMedicalRecordOfVacineListVacine != null) {
                    oldMedicalRecordOfVacineListVacine.getVacineList().remove(vacineListVacine);
                    oldMedicalRecordOfVacineListVacine = em.merge(oldMedicalRecordOfVacineListVacine);
                }
            }
            for (Appointment appointmentListAppointment : medicalRecord.getAppointmentList()) {
                MedicalRecord oldMedicalRecordOfAppointmentListAppointment = appointmentListAppointment.getMedicalRecord();
                appointmentListAppointment.setMedicalRecord(medicalRecord);
                appointmentListAppointment = em.merge(appointmentListAppointment);
                if (oldMedicalRecordOfAppointmentListAppointment != null) {
                    oldMedicalRecordOfAppointmentListAppointment.getAppointmentList().remove(appointmentListAppointment);
                    oldMedicalRecordOfAppointmentListAppointment = em.merge(oldMedicalRecordOfAppointmentListAppointment);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findMedicalRecord(medicalRecord.getIdMEDICALRECORD()) != null) {
                throw new PreexistingEntityException("MedicalRecord " + medicalRecord + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(MedicalRecord medicalRecord) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            MedicalRecord persistentMedicalRecord = em.find(MedicalRecord.class, medicalRecord.getIdMEDICALRECORD());
            List<Pet> petListOld = persistentMedicalRecord.getPetList();
            List<Pet> petListNew = medicalRecord.getPetList();
            List<Vacine> vacineListOld = persistentMedicalRecord.getVacineList();
            List<Vacine> vacineListNew = medicalRecord.getVacineList();
            List<Appointment> appointmentListOld = persistentMedicalRecord.getAppointmentList();
            List<Appointment> appointmentListNew = medicalRecord.getAppointmentList();
            List<String> illegalOrphanMessages = null;
            for (Pet petListOldPet : petListOld) {
                if (!petListNew.contains(petListOldPet)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Pet " + petListOldPet + " since its medicalRecord field is not nullable.");
                }
            }
            for (Vacine vacineListOldVacine : vacineListOld) {
                if (!vacineListNew.contains(vacineListOldVacine)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Vacine " + vacineListOldVacine + " since its medicalRecord field is not nullable.");
                }
            }
            for (Appointment appointmentListOldAppointment : appointmentListOld) {
                if (!appointmentListNew.contains(appointmentListOldAppointment)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Appointment " + appointmentListOldAppointment + " since its medicalRecord field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Pet> attachedPetListNew = new ArrayList<Pet>();
            for (Pet petListNewPetToAttach : petListNew) {
                petListNewPetToAttach = em.getReference(petListNewPetToAttach.getClass(), petListNewPetToAttach.getPetPK());
                attachedPetListNew.add(petListNewPetToAttach);
            }
            petListNew = attachedPetListNew;
            medicalRecord.setPetList(petListNew);
            List<Vacine> attachedVacineListNew = new ArrayList<Vacine>();
            for (Vacine vacineListNewVacineToAttach : vacineListNew) {
                vacineListNewVacineToAttach = em.getReference(vacineListNewVacineToAttach.getClass(), vacineListNewVacineToAttach.getVacinePK());
                attachedVacineListNew.add(vacineListNewVacineToAttach);
            }
            vacineListNew = attachedVacineListNew;
            medicalRecord.setVacineList(vacineListNew);
            List<Appointment> attachedAppointmentListNew = new ArrayList<Appointment>();
            for (Appointment appointmentListNewAppointmentToAttach : appointmentListNew) {
                appointmentListNewAppointmentToAttach = em.getReference(appointmentListNewAppointmentToAttach.getClass(), appointmentListNewAppointmentToAttach.getAppointmentPK());
                attachedAppointmentListNew.add(appointmentListNewAppointmentToAttach);
            }
            appointmentListNew = attachedAppointmentListNew;
            medicalRecord.setAppointmentList(appointmentListNew);
            medicalRecord = em.merge(medicalRecord);
            for (Pet petListNewPet : petListNew) {
                if (!petListOld.contains(petListNewPet)) {
                    MedicalRecord oldMedicalRecordOfPetListNewPet = petListNewPet.getMedicalRecord();
                    petListNewPet.setMedicalRecord(medicalRecord);
                    petListNewPet = em.merge(petListNewPet);
                    if (oldMedicalRecordOfPetListNewPet != null && !oldMedicalRecordOfPetListNewPet.equals(medicalRecord)) {
                        oldMedicalRecordOfPetListNewPet.getPetList().remove(petListNewPet);
                        oldMedicalRecordOfPetListNewPet = em.merge(oldMedicalRecordOfPetListNewPet);
                    }
                }
            }
            for (Vacine vacineListNewVacine : vacineListNew) {
                if (!vacineListOld.contains(vacineListNewVacine)) {
                    MedicalRecord oldMedicalRecordOfVacineListNewVacine = vacineListNewVacine.getMedicalRecord();
                    vacineListNewVacine.setMedicalRecord(medicalRecord);
                    vacineListNewVacine = em.merge(vacineListNewVacine);
                    if (oldMedicalRecordOfVacineListNewVacine != null && !oldMedicalRecordOfVacineListNewVacine.equals(medicalRecord)) {
                        oldMedicalRecordOfVacineListNewVacine.getVacineList().remove(vacineListNewVacine);
                        oldMedicalRecordOfVacineListNewVacine = em.merge(oldMedicalRecordOfVacineListNewVacine);
                    }
                }
            }
            for (Appointment appointmentListNewAppointment : appointmentListNew) {
                if (!appointmentListOld.contains(appointmentListNewAppointment)) {
                    MedicalRecord oldMedicalRecordOfAppointmentListNewAppointment = appointmentListNewAppointment.getMedicalRecord();
                    appointmentListNewAppointment.setMedicalRecord(medicalRecord);
                    appointmentListNewAppointment = em.merge(appointmentListNewAppointment);
                    if (oldMedicalRecordOfAppointmentListNewAppointment != null && !oldMedicalRecordOfAppointmentListNewAppointment.equals(medicalRecord)) {
                        oldMedicalRecordOfAppointmentListNewAppointment.getAppointmentList().remove(appointmentListNewAppointment);
                        oldMedicalRecordOfAppointmentListNewAppointment = em.merge(oldMedicalRecordOfAppointmentListNewAppointment);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = medicalRecord.getIdMEDICALRECORD();
                if (findMedicalRecord(id) == null) {
                    throw new NonexistentEntityException("The medicalRecord with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            MedicalRecord medicalRecord;
            try {
                medicalRecord = em.getReference(MedicalRecord.class, id);
                medicalRecord.getIdMEDICALRECORD();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The medicalRecord with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Pet> petListOrphanCheck = medicalRecord.getPetList();
            for (Pet petListOrphanCheckPet : petListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This MedicalRecord (" + medicalRecord + ") cannot be destroyed since the Pet " + petListOrphanCheckPet + " in its petList field has a non-nullable medicalRecord field.");
            }
            List<Vacine> vacineListOrphanCheck = medicalRecord.getVacineList();
            for (Vacine vacineListOrphanCheckVacine : vacineListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This MedicalRecord (" + medicalRecord + ") cannot be destroyed since the Vacine " + vacineListOrphanCheckVacine + " in its vacineList field has a non-nullable medicalRecord field.");
            }
            List<Appointment> appointmentListOrphanCheck = medicalRecord.getAppointmentList();
            for (Appointment appointmentListOrphanCheckAppointment : appointmentListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This MedicalRecord (" + medicalRecord + ") cannot be destroyed since the Appointment " + appointmentListOrphanCheckAppointment + " in its appointmentList field has a non-nullable medicalRecord field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(medicalRecord);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<MedicalRecord> findMedicalRecordEntities() {
        return findMedicalRecordEntities(true, -1, -1);
    }

    public List<MedicalRecord> findMedicalRecordEntities(int maxResults, int firstResult) {
        return findMedicalRecordEntities(false, maxResults, firstResult);
    }

    private List<MedicalRecord> findMedicalRecordEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(MedicalRecord.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public MedicalRecord findMedicalRecord(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(MedicalRecord.class, id);
        } finally {
            em.close();
        }
    }

    public int getMedicalRecordCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<MedicalRecord> rt = cq.from(MedicalRecord.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
